import json
from datetime import datetime
from typing import Optional

import uvicorn
from fastapi import FastAPI, Response, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from QueryService import queryService
from JWTUtils import create_access_token
from wechat import get_openid
from request_model import AliasAuthor, LoginModel, SubmitAliasRequest, ToggleLikeRequest,AddressSaveModel,EvaluateModel,TuanCreateModel

app = FastAPI()

# 添加CORS中间件配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 在开发环境下允许所有来源
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/")
def read_root():
    return {"Hello": "World"}
## 别名审核拒绝
@app.post("/jx3-waiguan/api/alias/audit/fail")
async def fail_audit(aliasAuthor:AliasAuthor):
    result = queryService().fail_audit(aliasAuthor.id)
    if result:
        return Response(content=json.dumps({"code": 200, "message": "success"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")

## 别名审核通过
@app.post("/jx3-waiguan/api/alias/audit/pass")
async def pass_audit(aliasAuthor:AliasAuthor):
    result = queryService().pass_audit(aliasAuthor.id)
    if result:
        return Response(content=json.dumps({"code": 200, "message": "success"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")


## 获取别名审核列表
@app.get("/jx3-waiguan/api/alias/audit/list")
async def getAliasAuditList(userId:str, page:int, limit:int):
    result = queryService().getAliasAuditList(userId, page, limit)
    if result is None or result == []:
        return Response(content=json.dumps({"code": 10001, "message": "没有数据"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")


## 获取价格走势1
@app.get("/jx3-waiguan/api/waiguan/priceHistory")
async def getPriceHistory(itemId:str, itemType:str, days:int):
    result = queryService().getPriceHistory(itemId, itemType, days)
    if result is None or result == []:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")

## 获取关注状态
@app.get("/jx3-waiguan/api/waiguan/isFollowd")
async def isFollowd(itemId:str, userId:str):
    result = queryService().is_followd(itemId, userId)
    if result is None:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")

## 获取关注列表
@app.get("/jx3-waiguan/api/waiguan/getFollowList")
async def getFollowList(userId:str):
    result = queryService().getFollowList(userId)
    if result is None:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")


## 关注外观
@app.post("/jx3-waiguan/api/waiguan/toggleLike")
async def toggleLike(request:ToggleLikeRequest):
    result = queryService().toggle_like_waiguan(request.waiguanId, request.userId)
    if result is not None and result.acknowledged:
        return Response(content=json.dumps({"code": 200, "message": "关注成功"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 500, "message": "关注失败"}), media_type="application/json")


#提交外观别名
@app.post("/jx3-waiguan/api/waiguan/submitAlias")
async def submitAlias(alias:SubmitAliasRequest):
    result = queryService().submitAlias(alias.waiguanId, alias.userId, alias.alias)
    return Response(content=json.dumps(result), media_type="application/json")

#### 根据itemId获取外观详情
@app.get("/jx3-waiguan/api/waiguan/detailByItemId")
async def getWaiguanDetailByItemId(itemId:int):
    result = queryService().getWaiguanDetailByItemId(itemId)
    if result is None :
        return Response(content=json.dumps({"code": 10012, "message": "暂无详情"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")

#根据id获取外观详情
@app.get("/jx3-waiguan/api/waiguan/detail")
async def getWaiguanDetail(id:str):
    result = queryService().getWaiguanDetail(id)
    if result is None:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")

#获取外观列表
@app.get("/jx3-waiguan/api/waiguan/list")
async def getWaiguanList(type: str, keyword: Optional[str] = None, page: int = 1, limit: int = 10):
    result = queryService().getWaiguanList(type, keyword, page, limit)
    if result is None:
        return Response(
            content=json.dumps({
                "code": 500, 
                "message": "查询失败"
            }), 
            media_type="application/json"
        )
    
    return Response(
        content=json.dumps({
            "code": 200,
            "data": result
        }), 
        media_type="application/json"
    )

#获取评价结果
@app.get("/jx3-waiguan/api/pintuan/getEvaluateResult")
async def getEvaluateResult(tuanId:str, userId:str, createrId:str=None):
    result = queryService().getEvaluateResult(tuanId, createrId, userId)
    if result is None:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")   



#评价拼团
@app.post("/jx3-waiguan/api/tuan/evaluate")
async def evaluate_tuan(evaluateData:EvaluateModel):
    result =  queryService().evaluate_tuan(evaluateData)
    if result is not None and result.acknowledged:
        return Response(content=json.dumps({"code": 200, "message": "success"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")

#获取拼团列表
@app.get("/jx3-waiguan/api/tuan/list")
async def getPintuanList(type: str, userId: Optional[str] = None, page: int = 1, limit: int = 10):
    result = queryService().getPintuanList(type, userId, page, limit)
    if result is None:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")

#根据Id获取拼团详情
@app.get("/jx3-waiguan/api/tuan/detail")
async def getPintuanDetail(id:str):
    result = queryService().getPintuanDetail(id)
    return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")

#更新拼团
@app.post("/jx3-waiguan/api/tuan/update")
async def update_tuan(pintuan:TuanCreateModel):
    result = queryService().update_tuan(pintuan)
    if result.acknowledged:
        return Response(content=json.dumps({"code": 200, "message": "success"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")

#创建拼团
@app.post("/jx3-waiguan/api/tuan/create")
async def create_tuan(pintuan:TuanCreateModel):
    result = queryService().create_tuan(pintuan)
    if result.acknowledged:
        return Response(content=json.dumps({"code": 200, "id": str(result.inserted_id)}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 500, "message": "error"}), media_type="application/json")

#根据userId获取用户信息
@app.get("/jx3-waiguan/api/getUserInfo")
async def getUserInfo(userId:str):
    user = queryService().queryUserByOpenId(userId)
    user['_id'] = user['_id'].__str__()
    if user is None:
        return Response(status_code=500,content=json.dumps(user), media_type="application/json")
    else:
        return Response(status_code=200,content=json.dumps(user), media_type="application/json")

#登录
@app.post("/jx3-waiguan/api/login")
async def login( loginModel: LoginModel):
    try:
        # 获取openid
        openid = get_openid(loginModel.code)

        # 查找或创建用户
        user = queryService().queryUserByOpenId(openid['openid'])
        if user is None:
            ## c创建用户
            user = {
                "open_id": openid['openid'],
                "session_key": openid['session_key'],
                "gender": loginModel.userInfo.get("gender", ""),
                "nickname": loginModel.userInfo.get("nickName", ""),
                "avatar_url": loginModel.userInfo.get("avatarUrl", ""),
                 "createTime":datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                "updateTime":datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                "deleted":False
            }
            queryService().save_user(user)
        # 生成token
        token = create_access_token({"sub": str(user['open_id'])})

        return {
            "code": 200,
            "message": "登录成功",
            "data": {
                "token": token,
                "user": {
                    "id": user['open_id'],
                    "nickname": user['nickname'],
                    "avatar_url": user['avatar_url']
                }
            }
        }

    except Exception as e:
        raise HTTPException(
            status_code=400,
            detail=str(e)
        )

#获取热门外观
@app.get("/jx3-waiguan/api/getHot")
async def say_hello2():
    test  = queryService().get_hot10()
    ###遍历Cursor,将结果转换为列表
    result = []
    for doc in test:
        doc['_id'] = doc['_id'].__str__()
        result.append(doc)
    return result

# 更新地址
@app.put("/jx3-waiguan/api/address/update")
def update_address(address:AddressSaveModel):
    # 确保 _id 字段是字符串类型
    result = queryService().save_or_update_address(AddressSaveModel(**address.model_dump()))
    if result.acknowledged:
        return Response(content=json.dumps({"code": 200, "message": "success"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")

#保存地址
@app.post("/jx3-waiguan/api/address/save")
def save_address(address: AddressSaveModel):
    # 给address添加创建时间和修改时间，并进行格式化
    current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    address_dic = address.model_dump()
    address_dic['createTime'] = current_time
    address_dic['updateTime']= current_time
    result = queryService().save_or_update_address(AddressSaveModel(**address_dic))
    if result.acknowledged:
        return Response(content=json.dumps({"code": 200, "message": "success"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")

## 获取地址详情
@app.get("/jx3-waiguan/api/address/getAddressById")
def get_address_detail(id:str):
    result = queryService().get_address_by_id(id)
    ## 将 ObejctId 转换为字符串
    result['_id'] = result['_id'].__str__()
    if result is None:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "data": result}), media_type="application/json")

##根据_id删除地址
@app.delete("/jx3-waiguan/api/address/delete")
def delete_address_by_id(addressId,timestamp:int):
    if timestamp is None:
        return Response(content=json.dumps({"code": 500, "message": "缺少参数"}), media_type="application/json")
    result = queryService().delete_address(addressId)
    if result.acknowledged:
        return Response(content=json.dumps({"code": 200, "message": "success"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")

##根据userId查询用户地址列表
@app.get("/jx3-waiguan/api/getAddressList")
def get_address_by_user_id(userId:str,timestamp:int):
    if timestamp is None:
        return Response(content=json.dumps({"code": 500, "message": "缺少参数"}), media_type="application/json")
    result = queryService().get_address_by_user_id(userId)
    if result is None:
        return Response(content=json.dumps({"code": 500, "message": "fail"}), media_type="application/json")
    else:
        return Response(content=json.dumps({"code": 200, "message": "success", "data": result}), media_type="application/json")




if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8992)